package phaseI;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;

public class PhaseIDriver {

	public static ArrayList<String> getMatchedTokens(String regex, String filePath) {
		Parser parser = new Parser(regex);
		HashMap<String, SyntaxTree> regexTrees = parser.getTrees();
		
		//Convert trees to DFA tables and create scanners for each table
		HashMap<String, NFATable> dfaTables = new HashMap<String, NFATable>();
		HashMap<String, DFAScanner> dfaScanners = new HashMap<String, DFAScanner>();
		for (String identifier : regexTrees.keySet())
		{
			SyntaxTree tree = regexTrees.get(identifier);
			NFATable nfa = NFACombiner.navigateTreeWithStack(tree);
			if (nfa != null) {
				
				DFATable dfa = DFATable.convertFromNFA(nfa);
				if (dfa != null) {
					dfaTables.put(identifier, dfa);
					//Create DFA scanner for dfa table
					DFAScanner scanner = new DFAScanner(dfa);
					dfaScanners.put(identifier, scanner);
				}
			}
		}
		
		ArrayList<String> matches = null;
		try {
			FileInputStream fStream = new FileInputStream(filePath);
			BufferedReader buffReader = new BufferedReader(new InputStreamReader(fStream));
			matches = new ArrayList<String>();
			
			//Parse text file and check if a match occurred each time a new character is read
			String currLine;
			while ((currLine = buffReader.readLine()) != null) {
				StringBuilder token = new StringBuilder();
				char[] charArray = currLine.toCharArray();
				for (char c : charArray) {
					token.append(c);
					
					DFAScanner scanner = null;
					for (String identifier : dfaScanners.keySet()) {
						scanner = dfaScanners.get(identifier);
						if (scanner.matches(token.toString())) {
							
							//System.out.println(identifier+ " " +token);
							matches.add(token.toString());
							
							token = new StringBuilder();
							break;
						}
					}
				}
				
			}
			buffReader.close();
		} catch (IOException e) {
			System.out.println("File not found at: "+filePath);
			System.exit(0);
		}
		
		return matches;
	}
	
	/**
	 * @param args
	 */
	/*public static void main(String[] args) {
		
		if (args.length < 2) {
			System.out.println("Wrong number of arguments!");
			System.out.println("Usage: <regex-file> <text-file>");
		}
		else {
			String regexPath = args[0];
			String inputFilePath = args[1];
			
			Parser parser = new Parser(regexPath);
			HashMap<String, SyntaxTree> regexTrees = parser.getTrees();
			
			//Convert trees to DFA tables and create scanners for each table
			HashMap<String, NFATable> dfaTables = new HashMap<String, NFATable>();
			HashMap<String, DFAScanner> dfaScanners = new HashMap<String, DFAScanner>();
			HashMap<String, NFAScanner> nfaScanners = new HashMap<String, NFAScanner>();
			for (String identifier : regexTrees.keySet())
			{
				SyntaxTree tree = regexTrees.get(identifier);
				//System.out.println(tree.levelorder());
				NFATable nfa = NFACombiner.navigateTreeWithStack(tree);
				if (nfa != null) {
					
					DFATable dfa = DFATable.convertFromNFA(nfa);
					//System.out.println(dfa);
					//System.out.println(dfa.getEndStates());
					
					if (dfa != null) {
						dfaTables.put(identifier, dfa);
						
						//Create DFA scanner for dfa table
						DFAScanner scanner = new DFAScanner(dfa);
						dfaScanners.put(identifier, scanner);
					}
					
					nfaScanners.put(identifier, new NFAScanner(nfa));
				}
			}
			
			try {
				FileInputStream fStream = new FileInputStream(inputFilePath);
				BufferedReader buffReader = new BufferedReader(new InputStreamReader(fStream));
				
				//Parse text file and check if a match occurred each time a new character is read
				
				String currLine;
				while ((currLine = buffReader.readLine()) != null) {
					StringBuilder token = new StringBuilder();
					char[] charArray = currLine.toCharArray();
					for (char c : charArray) {
						token.append(c);
						
						DFAScanner scanner = null;
						for (String identifier : dfaScanners.keySet()) {
							scanner = dfaScanners.get(identifier);
							if (scanner.matches(token.toString())) {
								System.out.println(identifier+ " " +token);
								token = new StringBuilder();
								break;
							}
						}
					}
					
				}
				
			} catch (IOException e) {
				System.out.println("Text file not found!");
			}
			
			System.out.println("\nScanning using NFA scanners:");
			try {
				FileInputStream fStream = new FileInputStream(inputFilePath);
				BufferedReader buffReader = new BufferedReader(new InputStreamReader(fStream));
				
				//Parse text file and check if a match occurred each time a new character is read
				String currLine;
				while ((currLine = buffReader.readLine()) != null) {
					StringBuilder token = new StringBuilder();
					char[] charArray = currLine.toCharArray();
					for (char c : charArray) {
						token.append(c);
						
						NFAScanner scanner = null;
						for (String identifier : dfaScanners.keySet()) {
							scanner = nfaScanners.get(identifier);
							if (scanner.matches(token.toString())) {
								System.out.println(identifier+ " " +token);
								token = new StringBuilder();
								break;
							}
						}
					}
					
				}
				
			} catch (IOException e) {
				System.out.println("Text file not found!");
			}
		}
		
	}
		
	public static ArrayList<String> tokenize(String filePath) throws IOException {
		BufferedReader fstream = new BufferedReader(new FileReader(filePath));
		ArrayList<String> retval = new ArrayList<String>();
		String s = "";
		
		while(true) {
			int c = fstream.read();
			
			if (c == -1) {
				if (!s.equals("")) retval.add(s);
				break;
			}
			
			//System.out.print((char)c);
			
			switch ((char)c) {
			//whitespace
			case ' ':
			case '\n':
			case '\r':
			case '\t':
			case '\f':
				if (!s.equals("")) retval.add(s);
				s = "";
				continue;
			default:
				s += (char)c;
			}
		}
		fstream.close();
		return retval;
	}*/

}
